package gmu.swe.project.peer;

import gmu.swe.project.io.ConfigFileParser;
import gmu.swe.project.io.DirectoryReader;
import gmu.swe.project.query.Query;
import gmu.swe.project.query.QueryResultSet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.UUID;

/**
 * 	On startup the Peer (client) should read the configuration file to find the directory of the shared 
 *	files.  It should do a listing of the directory and create a PeerInfo object for each file in the
 *	directory.  It should then add all PeerInfo objects to the ClientFileSet.  The client then needs
 *	to read the configuration file for the server list.  It should query each server in turn, asking
 *	for it's workload.  Upon receipt of all replies, the client should choose the server with the least
 *	amount of workload and send the ClientFileSet across the ServerSocket to the it.
 *
 *	********Need to enforce a set location for the config file.   ******
 * Current design on the configuration file:
 * <?xml version="1.0"?>
 * <config>
 * 	<!--IP Address of this server - whatever kind it is -->
 * 	<ip_address>192.168.10.3</ip_address>
 *  <tracker>
 * 		<!-- Port that the tracker will listen on for Peers and Trackers -->
 * 		<listening_port>10398</listening_port>
 *  </tracker>
 *  <peer>
 * 		<!-- Directory of shared files -->
 * 		<shared_file_directory>C:/Temp</shared_file_directory>
 *  </peer>
 * 	<!-- Registry servers -->
 * 	<registries>
 *		<registry>
 *			<svr_ip_address>192.168.10.2</svr_ip_address>
 *			<port>12345</port>
 *		</registry>
 *		<registry>
 *			<svr_ip_address>192.168.10.3</svr_ip_address>
 *			<port>23456</port>
 *		</registry>
 *	</registries>
 * </config>
 *
 * @author Christina Bradbury
 * @author 
 * @author 
 * @author
 *
 */
public class Peer {

	public void main(String args[]) {
		
		Socket peerSocket = null;
		ObjectOutputStream oos = null;
		ObjectInputStream ois = null;
		
		/**  ***********NEED TO QUERY REGISTRY SERVER FOR TRACKER - handled by Stacy ********** **/
		//Registry server will return Tracker and ports, at which point we can get rid of the following lines of code.
		//TrackerInfo trackerInfo = Registry.getTrackerInfo();
		String tracker = "localhost";
		Integer listeningPort = 13098;
			
		//read the configuration file
		PeerInfo peerInfo = this.readConfigFile();
		
		try {
			//create new socket
			peerSocket = new Socket(tracker,listeningPort);
			//connect an output stream to it to send data to the server
			oos = new ObjectOutputStream(peerSocket.getOutputStream());
			//connect a reader on it to receive data from the server
			ois = new ObjectInputStream(peerSocket.getInputStream());
			//send the PeerInfo to the server
			oos.writeObject(peerInfo);
			//once the client has an ACK back it's info has been successfully loaded onto the server
			String ack = (String) ois.readObject();
			
			//send the server a query
			/**************** QUERY SHOULD COME FROM UI - handled by Dan***************************/
			String queryFile = "Test1.txt";
			//Add the query to a message. ID will be returned in the ACK
			Query query = new Query();
			query.setQuery(queryFile);
			query.setId(UUID.randomUUID().toString());
			query.setType(Query.PEER_QUERY);

			//send the Query to the server
			oos.writeObject(query);
			//wait for the response
			QueryResultSet queryResultSet = (QueryResultSet) ois.readObject();
			/**************** POST RESULTS TO UI - handled by Dan***************************/
			
		} catch(UnknownHostException uhex) {
			//do something
		} catch(IOException ioex) {
			//do something
		} catch(ClassNotFoundException cnfex) {
			//do something
		} finally {
			//close the reader, writer and socket
			try {
				oos.close();
			} catch(Exception ex) {}
			try {
				ois.close();
			} catch(Exception ex) {}
			try {
				peerSocket.close();
			} catch(Exception ex) {}
		}
	}
	
	private PeerInfo readConfigFile() {
		
		PeerInfo info = new PeerInfo();
		
		//read the config file
		String location = System.getProperty("CONFIG_FILE_LOCATION", "C:\\Temp\\config.xml");
		ConfigFileParser parser = new ConfigFileParser(location);

		//Create the object that will be sent to the server
		info.setIpAddress(parser.getIpAddress());
		//get the list of files in the directory
		DirectoryReader reader = new DirectoryReader(parser.getSharedDirectory());
		if(reader.queryDirectory()) {
			info.setFiles(reader.getFilesInDirectory());
		}
		//set the unique id on the peer info; it will be returned in the ACK
		info.setId(UUID.randomUUID().toString());
		
		return info;
				
	}
}
